package com.spzx.product.service.impl;

import com.spzx.common.core.utils.StringUtils;
import com.spzx.common.security.utils.SecurityUtils;
import com.spzx.product.service.ITestService;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class ITestServiceImpl implements ITestService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void testLock(HttpServletRequest request) {
        //todo 0.设置锁的独一无二的UUID值
        String uuid = UUID.
                randomUUID()
                .toString().
                replaceAll
                        ("-", "");
        //todo 1.尝试获取锁并设置过期时间
        Boolean flag = stringRedisTemplate
                .opsForValue()
                .setIfAbsent("lock", uuid,
                        1, TimeUnit.SECONDS);
        //todo 2.成功获取锁
        if (flag) {
            try {
                System.out.println("获取锁");
                //1.从redis中通过key num获取值  key提前手动设置 num 初始值：0
                String value = stringRedisTemplate.opsForValue().get("num");
                //2.如果值为空则非法直接返回即可
                if (StringUtils.isBlank(value)) {
                    return;
                }
                //3.对num值进行自增加一
                int num = Integer.parseInt(value);
                stringRedisTemplate
                        .opsForValue().
                        set("num", String.valueOf(++num));
            } catch (Exception e) {
                System.out.println("异常捕获");
            } finally {
                String script = """
                        if redis.call('get',KEYS[1]) == ARGV[1]
                        then return redis.call('del',KEYS[1])
                        else return 0
                        end
                        """;
                Boolean lock = stringRedisTemplate.execute(
                        new DefaultRedisScript<>(script, Boolean.class),
                        Arrays.asList("lock"),
                        uuid
                );
            }
        } else {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            //todo 3.获取锁失败,重新获取
            System.out.println("重试");
            this.testLock(request);
        }
    }
}